package cn.ydxiaoshuai.modules.util;

import cn.ydxiaoshuai.common.api.vo.weixin.WeiXinConts;
import cn.ydxiaoshuai.common.util.ImageUtil;
import cn.ydxiaoshuai.common.util.ImgCheckHttpUtil;
import cn.ydxiaoshuai.modules.weixin.po.WXAccessToken;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

/**
 * @author xavier
 * @className WeXinSecurityUtil
 * @Description 微信安全检查服务
 * @Date 2020/9/18-15:22
 **/
@Slf4j
public class WeiXinSecurityUtil {
    private static Integer IMG_CHECK4 = 87014;
    private static Integer IMG_CHECK5 = 87015;
    private static Integer IMG_CHECK0 = 0;
    private static Integer IMG_WIDTH = 750;
    private static Integer IMG_HEIGHT = 1334;
    /**
     * 图片检测接口
     */
    private static String IMG_SEC_URL = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=";

    /**
     * @author xavier
     * @Description 图片安全检查
     * @Date  2020/9/29
     * @param imageUrl 图片公网地址
     * @param access_token 微信的token
     * @return cn.ydxiaoshuai.modules.weixin.po.WXAccessToken
     **/
    public static WXAccessToken checkImg(String imageUrl,String access_token) throws Exception{
        WXAccessToken bean;
        BufferedImage bufferedImage = ImageUtil.imgUrlConvertBufferedImage(imageUrl);
        String url = IMG_SEC_URL + access_token;
        //750px * 1334px
        if (bufferedImage.getWidth() > IMG_WIDTH && bufferedImage.getHeight() > IMG_HEIGHT) {
            //缩放图片
            byte[] newImage = ImageUtil.zoomImageByte(bufferedImage);
            String result = ImgCheckHttpUtil.uploadFile(url,newImage);
            log.info(result);
            bean = JSON.parseObject(result, WXAccessToken.class);
            System.out.println("general缩放图片检测结果 = " + result);
        } else {
            ByteArrayOutputStream outputStreamSource = new ByteArrayOutputStream();
            ImageIO.write(bufferedImage, "jpg", outputStreamSource);
            String result = ImgCheckHttpUtil.uploadFile(url,outputStreamSource.toByteArray());
            log.info(result);
            bean = JSON.parseObject(result, WXAccessToken.class);
            System.out.println("general图片检测结果 = " + result);
        }
        return bean;
    }

    /**
     * @author xavier
     * @Description 图片安全检查
     * @Date  2020/9/29
     * @param file 要检测的图片
     * @param access_token 微信的token
     * @return cn.ydxiaoshuai.modules.weixin.po.WXAccessToken
     **/
    public static WXAccessToken checkImg(MultipartFile file,String access_token) throws Exception{
        WXAccessToken bean;
        BufferedImage bufferedImage = InputImage(file);
        String url = IMG_SEC_URL + access_token;
        //750px * 1334px 
        if (bufferedImage.getWidth() > IMG_WIDTH || bufferedImage.getHeight() > IMG_HEIGHT) {
           //缩放图片
            byte[] newImage = ImageUtil.zoomImageByte(file.getBytes());
            String result = ImgCheckHttpUtil.uploadFile(url,newImage);
            log.info(result);
            bean = JSON.parseObject(result, WXAccessToken.class);
            System.out.println("general缩放图片检测结果 = " + result);
        } else {
            String result = ImgCheckHttpUtil.uploadFile(url,file);
            log.info(result);
            bean = JSON.parseObject(result, WXAccessToken.class);
            System.out.println("general图片检测结果 = " + result);
        }
        return bean;
    }

    /**
     * @author xavier
     * @Description 图片安全检查
     * @Date  2020/9/18 15:25
     * @param file 要检测的图片
     * @param weiXinConts 获取微信的token
     * @return cn.ydxiaoshuai.modules.weixin.po.WXAccessToken
     **/
    public static WXAccessToken checkImg(MultipartFile file,WeiXinConts weiXinConts){
        WXAccessToken bean = new WXAccessToken();
        BufferedImage bufferedImage = InputImage(file);
        //750px x 1334px
        if (bufferedImage.getWidth() > IMG_WIDTH || bufferedImage.getHeight() > IMG_HEIGHT) {
            bean.setErrcode(0);
            bean.setErrmsg("ok");
        } else {
            String url = IMG_SEC_URL + weiXinConts.getAccess_token();
            String result = ImgCheckHttpUtil.uploadFile(url, file);
            log.info(result);
            bean = JSON.parseObject(result, WXAccessToken.class);
            if (IMG_CHECK0.equals(bean.getErrcode())) {
                bean.setErrcode(0);
                bean.setErrmsg("ok");
            } else if (IMG_CHECK5.equals(bean.getErrcode())) {
                bean.setErrcode(0);
                bean.setErrmsg("ok");
            } else if (IMG_CHECK4.equals(bean.getErrcode())) {
                bean.setErrcode(bean.getErrcode());
                bean.setErrmsg(bean.getErrmsg());
            } else {
                bean.setErrcode(0);
                bean.setErrmsg("ok");
            }
            System.out.println("图片检测结果 = " + result);
        }
        return bean;
    }
    /**
     * @param file 图片文件
     * @return java.awt.image.BufferedImage
     * @author xavier
     * @Description MultipartFile 转 BufferedImage
     * @Date 2020/9/15 16:44
     **/
    public static BufferedImage InputImage(MultipartFile file) {
        BufferedImage srcImage = null;
        try {
            FileInputStream in = (FileInputStream) file.getInputStream();
            srcImage = javax.imageio.ImageIO.read(in);
        } catch (IOException e) {
            System.out.println("读取b图片文件出错！" + e.getMessage());
        }
        return srcImage;
    }

    /**
     * 缩放图片方法
     *
     * @param srcImageFile 要缩放的图片路径
     * @param result       缩放后的图片路径
     * @param height       目标高度像素
     * @param width        目标宽度像素
     * @param bb           是否补白
     */
    public final static void scale(File srcImageFile, String result, int height, int width, boolean bb) {
        try {
            // 缩放比例
            double ratio = 0.0;
            File f = srcImageFile;
            BufferedImage bi = ImageIO.read(f);
            //bi.SCALE_SMOOTH  选择图像平滑度比缩放速度具有更高优先级的图像缩放算法。
            Image itemp = bi.getScaledInstance(width, height, BufferedImage.SCALE_SMOOTH);
            // 计算比例
            if ((bi.getHeight() > height) || (bi.getWidth() > width)) {
                double ratioHeight = (new Integer(height)).doubleValue() / bi.getHeight();
                double ratioWhidth = (new Integer(width)).doubleValue() / bi.getWidth();
                if (ratioHeight > ratioWhidth) {
                    ratio = ratioHeight;
                } else {
                    ratio = ratioWhidth;
                }
                //仿射转换
                AffineTransformOp op = new AffineTransformOp(AffineTransform
                        //返回表示剪切变换的变换
                        .getScaleInstance(ratio, ratio), null);
                //转换源 BufferedImage 并将结果存储在目标 BufferedImage 中。
                itemp = op.filter(bi, null);
            }
            //补白
            if (bb) {
                BufferedImage image = new BufferedImage(width, height,
                        //构造一个类型为预定义图像类型之一的 BufferedImage。
                        BufferedImage.TYPE_INT_RGB);
                //创建一个 Graphics2D，可以将它绘制到此 BufferedImage 中。
                Graphics2D g = image.createGraphics();
                //控制颜色
                g.setColor(Color.white);
                // 使用 Graphics2D 上下文的设置，填充 Shape 的内部区域。
                g.fillRect(0, 0, width, height);
                if (width == itemp.getWidth(null)) {
                    g.drawImage(itemp, 0, (height - itemp.getHeight(null)) / 2,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                } else {
                    g.drawImage(itemp, (width - itemp.getWidth(null)) / 2, 0,
                            itemp.getWidth(null), itemp.getHeight(null),
                            Color.white, null);
                }

                g.dispose();
                itemp = image;
            }
            System.out.println(result);
            File outFile = new File(result);
            if (!outFile.exists() && !outFile.isDirectory()) {
                outFile.mkdir();
                ImageIO.write((BufferedImage) itemp, "JPEG", outFile);

            } else {
                ImageIO.write((BufferedImage) itemp, "JPEG", outFile);
            }
            //输出压缩图片

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
